package com.landian.commons.base.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * @author caojl
 * @create 2016/3/2
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class ResultDTO<T> implements Serializable {

    private static final int SUCCESS_CODE = 0;
    private static final int DEFAULT_ERROR_CODE = -1;

    /**
     * 数据，真正的结果对象
     */
    T model;
    /**
     * 调用是否出错
     */
    private boolean success;
    /**
     * 错误码
     */
    private int errorCode;
    /**
     * 错误信息
     */
    private String errorMsg;

    /**
     * 代替原有的successResult方法<br/>
     * 如果传入的model与T不相符时，会在编译期报错<br/>
     * 举例：<br/>
     * ResultDTO&lt;Integer&gt; result1 = ResultDTO.success("String");  -->  IDE报错<br/>
     * ResultDTO&lt;Integer&gt; result2 = ResultDTO.successResult("String");  -->  运行期抛出ClassCastException异常<br/>
     * 另外，不建议model为Void，如果不需要返回数据，那也就没有必要用ResultDTO
     */
    public static <T> ResultDTO<T> success(T model){
        return new ResultDTO<T>(model,true, SUCCESS_CODE, null);
    }

    /**
     * 代替原有的failResult方法，详看#successfy方法的说明
     * @see ResultDTO#success(Object)
     */
    public static <T> ResultDTO<T> fail(int errorCode, String errorMsg,T model){
        return new ResultDTO<T>(model,false,errorCode,errorMsg);
    }

    public static ResultDTO fail(String errorMsg){
        return ResultDTO.builder().errorCode(DEFAULT_ERROR_CODE).errorMsg(errorMsg).build();
    }

    public static ResultDTO fail(int errorCode, String errorMsg){
        return ResultDTO.builder().errorCode(errorCode).errorMsg(errorMsg).build();
    }

    public boolean isFail() {
        return !isSuccess();
    }

    public Result<T> toResult(){
        return new Result(model, errorCode, errorMsg);
    }
}
